package gov.pbc.nn.kjgl.maintenance.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import gov.pbc.nn.core.bdf.IUserSelect;
import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.bdf.entity.User;
import gov.pbc.nn.core.bdf.service.UserService.DefaultUserRowMapper;
import gov.pbc.nn.core.dao.CommonHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreJdbcDao;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.Constants;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyPlan;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyPlanDept;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyPlanHeader;
import gov.pbc.nn.uflo.UfloUtils;
import gov.pbc.nn.uflo.entity.Opinion;

import javax.annotation.Resource;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.ParseResult;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.StartProcessInfo;
import com.bstek.uflo.service.TaskOpinion;

@Component
public class SysEmergencyPlanPR_old implements IUserSelect {

	@Resource(name = CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao hibernateDao;

	@Resource(name = PbcnnCoreJdbcDao.BEAN_ID)
	private PbcnnCoreJdbcDao pbcnnCoreJdbcDao;

	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao pbcnnCoreHibernateDao;

	@Autowired
	@Qualifier(ProcessClient.BEAN_ID)
	private ProcessClient processClient;

	@Autowired
	@Qualifier(TaskClient.BEAN_ID)
	private TaskClient taskClient;

	@Autowired
	private SysChangePR sysChangePR;

	/**
	 * IUserSelect接口实现的方法，用于import添加人员控件的数据获取方式为次方法
	 */
	@Override
	public void loadUsers(Page<IUser> page, Criteria criteria, Map<String, Object> params) throws Exception {
		String deptId = ContextHolder.getLoginUser().getDepts().get(0).getId();
		String companyId = ContextHolder.getLoginUser().getCompanyId();
		String sql = "SELECT T.* FROM (SELECT U.*, D.ID_ as DEPT_ID_,D.NAME_ as DEPT_NAME_ FROM t_user U LEFT JOIN bdf2_user_dept UD ON U.USERNAME_ = UD.USERNAME_ LEFT JOIN t_dept D ON UD.DEPT_ID_ = D.ID_ order by D.ID_,U.USERNAME_) T WHERE T.DEPT_ID_=:deptId and T.COMPANY_ID_=:companyId ";
		ParseResult result = pbcnnCoreJdbcDao.parseCriteria(criteria, true, "T");
		if (result != null) {
			StringBuffer sb = result.getAssemblySql();
			Map<String, Object> valueMap = result.getValueMap();
			sql += " and " + sb.toString();
			valueMap.put("deptId", deptId);
			valueMap.put("companyId", companyId);
			pbcnnCoreJdbcDao.pagingQuery(page, sql, new DefaultUserRowMapper(), valueMap);
		} else {
			Map<String, Object> valueMap = new HashMap<String, Object>();
			valueMap.put("deptId", deptId);
			valueMap.put("companyId", companyId);
			pbcnnCoreJdbcDao.pagingQuery(page, sql, new DefaultUserRowMapper(), valueMap);
		}

	}

	/**
	 * 获取当前登录人部门中岗位为 技术主管 的人
	 * 
	 * @return
	 */
	@DataProvider
	public List<Map<String, Object>> getCto(String sysId) {
		return sysChangePR.loadCTO(sysId);
	}

	/**
	 * 获取SysEmergencyPlan
	 * 
	 * @param page
	 */
	@DataProvider
	public void loadSysEmergencyPlan(Page<SysEmergencyPlan> page, Criteria criteria) {
		DetachedCriteria query = this.hibernateDao.buildDetachedCriteria(criteria, SysEmergencyPlan.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		this.hibernateDao.pagingQuery(page, query);
	}

	/**
	 * 通过SysEmergencyPlan的 ID获取SysEmergencyPlanDept
	 * 
	 * @param planId
	 * @return
	 */
	@DataProvider
	public List<SysEmergencyPlanDept> loadSysEmergencyPlanDept(String planId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(SysEmergencyPlanDept.class);
		criteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		criteria.add(Restrictions.eq("planId", planId));
		List<SysEmergencyPlanDept> values = (List<SysEmergencyPlanDept>) this.hibernateDao.query(criteria);
		if (!values.isEmpty()) {
			return values;
		}
		return null;
	}

	/**
	 * 通过SysEmergencyPlan 的ID获取 SysEmergencyPlanHeader
	 * 
	 * @param planId
	 * @return
	 */
	@DataProvider
	public List<SysEmergencyPlanHeader> loadSysEmergencyPlanHeader(String planId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(SysEmergencyPlanHeader.class);
		criteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		criteria.add(Restrictions.eq("planId", planId));
		List<SysEmergencyPlanHeader> values = (List<SysEmergencyPlanHeader>) this.hibernateDao.query(criteria);
		if (!values.isEmpty()) {
			return values;
		}
		return null;
	}

	/**
	 * 维护SysEmergencyPlan及其子对象
	 * 
	 * @param plan
	 */
	@Transactional
	@DataResolver
	public void savePlan(List<SysEmergencyPlan> plan) {
		for (SysEmergencyPlan p : plan) {
			if (EntityUtils.getState(p).equals(EntityState.NEW)) {
				p.setState(1);// 实体状态state设置为1表示 新建
				this.hibernateDao.save(p);
			} else if (EntityUtils.getState(p).equals(EntityState.MODIFIED)) {
				this.hibernateDao.update(p);
			}
			List<SysEmergencyPlanDept> spd = EntityUtils.getValue(p, "planDept");
			List<SysEmergencyPlanHeader> sph = EntityUtils.getValue(p, "planHeader");
			if (spd != null) {
				for (SysEmergencyPlanDept pd : spd) {
					if (EntityUtils.getState(pd).equals(EntityState.NEW)) {
						pd.setPlanId(p.getId());
						this.hibernateDao.save(pd);
					} else if (EntityUtils.getState(pd).equals(EntityState.DELETED)) {
						this.hibernateDao.delete(pd);
					}
				}
			}
			if (sph != null) {
				for (SysEmergencyPlanHeader ph : sph) {
					if (EntityUtils.getState(ph).equals(EntityState.NEW)) {
						ph.setPlanId(p.getId());
						this.hibernateDao.save(ph);
					} else if (EntityUtils.getState(ph).equals(EntityState.DELETED)) {
						this.hibernateDao.delete(ph);
					}
				}
			}
		}
	}

	/**
	 * 删除SysEmergencyPlan及其子对象
	 * 
	 * @param num
	 */
	@Transactional
	@Expose
	public void deletePlan(List<String> num) {
		for (int i = 0; i < num.size(); i++) {
			this.hibernateDao.delete(num.get(i), SysEmergencyPlan.class);

			List<String> planDept = this.getSysEmergencyPlanDeptByPlanId(num.get(i));
			if (planDept != null) {
				for (String s : planDept) {
					this.hibernateDao.delete(s, SysEmergencyPlanDept.class);
				}
			}

			List<String> planHeader = this.getSysEmergencyPlanHeaderByPlanId(num.get(i));
			if (planHeader != null) {
				for (String s : planHeader) {
					this.hibernateDao.delete(s, SysEmergencyPlanHeader.class);
				}
			}
		}
	}

	/**
	 * 根据SysEmergencyPlan的ID获取SysEmergencyPlanDept
	 * 
	 * @param id
	 * @return
	 */
	public List<String> getSysEmergencyPlanDeptByPlanId(String id) {
		String hql = "select a.id from SysEmergencyPlanDept as a,SysEmergencyPlan as b where a.planId=b.id and b.id=:id and a.invalid=false";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", id);
		List<String> valus = this.hibernateDao.query(hql, map);
		if (!valus.isEmpty()) {
			return valus;
		}
		return null;
	}

	/**
	 * 根据SysEmergencyPlan 的ID获取SysEmergencyPlanHeader
	 * 
	 * @param id
	 * @return
	 */
	public List<String> getSysEmergencyPlanHeaderByPlanId(String id) {
		String hql = "select a.id from SysEmergencyPlanHeader as a,SysEmergencyPlan as b where a.planId=b.id and b.id=:id and a.invalid=false";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", id);
		List<String> valus = this.hibernateDao.query(hql, map);
		if (!valus.isEmpty()) {
			return valus;
		}
		return null;
	}

	/**
	 * 提交到技术主管审核
	 * 
	 * @param plan
	 * @param cto
	 */
	@Transactional
	@Expose
	public void commitJSZG(SysEmergencyPlan plan, String cto) {
		// 开始流程
		plan.setState(5);// 实体状态state设置为5表示 审核中
		this.hibernateDao.update(plan);
		StartProcessInfo info = new StartProcessInfo();
		info.setPromoter(ContextHolder.getLoginUserName());
		info.setCompleteStartTask(true);
		info.setBusinessId(plan.getId());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("cto", cto);
		map.put("state", 5);
		map.put("sysId", plan.getSysId());
		map.put("agree", 1);
		info.setVariables(map);
		processClient.startProcessByName("应急计划", info);
	}

	/**
	 * 通过businessID来获取SysEmergencyPlan,
	 * 
	 * @param planId
	 * @return
	 */
	@DataProvider
	public SysEmergencyPlan loadSysEmergencyPlanBySh(String planId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(SysEmergencyPlan.class);
		criteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		criteria.add(Restrictions.eq("id", planId));
		List<SysEmergencyPlan> ls = (List<SysEmergencyPlan>) this.hibernateDao.query(criteria);
		if (!ls.isEmpty()) {
			return ls.get(0);
		}
		return null;
	}

	/**
	 * 保存审批意见
	 * 
	 * @param taskId
	 * @param opinionText
	 * @param i
	 */
	@Transactional
	@Expose
	public void opinionSh(String taskId, String opinionText, int i, SysEmergencyPlan plan) {
		TaskOpinion option = new TaskOpinion(opinionText);
		Task task = taskClient.getTask(Long.valueOf(taskId));
		taskClient.start(Long.valueOf(taskId));
		final Opinion o = new Opinion();
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setBusKey(task.getBusinessId());
		o.setTaskId(Long.parseLong(taskId));
		o.setTaskName(task.getTaskName());
		o.setNodeName(task.getNodeName());
		o.setProcessName("应急计划");
		o.setBusTable("T_SYS_EMERGENCY_PLAN");
		o.setOpinion(opinionText);
		o.setUsername(ContextHolder.getLoginUser().getUsername());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setNodeName(task.getNodeName());
		this.pbcnnCoreHibernateDao.save(o);
		Map<String, Object> map = new HashMap<String, Object>();
		int agree = 0;
		if (i == 1) {
			if (task.getNodeName().equals("运维部门主管审核")) {
				plan.setState(10);// 实体状态state设置为10表示 已通过
				this.hibernateDao.update(plan);
			}
			agree = 1;
		} else if (i == 0) {
			agree = 0;
		}
		map.put("agree", agree);
		taskClient.complete(Long.valueOf(taskId), map, option);
	}

	/**
	 * 再次提交
	 * 
	 * @param taskId
	 */
	@Expose
	public void commitAgain(String taskId) {
		taskClient.start(Long.valueOf(taskId));
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("agree", 1);
		taskClient.complete(Long.valueOf(taskId), map);
	}

	/**
	 * 撤销申请
	 * 
	 * @param taskId
	 */
	@Transactional
	@Expose
	public void cheXiao(String taskId, SysEmergencyPlan plan) {
		plan.setState(20);// 实体状态state设置为20表示 已撤销
		this.hibernateDao.update(plan);
		taskClient.start(Long.valueOf(taskId));
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("state", 20);
		taskClient.forward(Long.valueOf(taskId), "归档", map);
	}

	/**
	 * 维护单个SysEmergencyPlan
	 * 
	 * @param plan
	 */
	@Transactional
	@DataResolver
	public void saveOne(SysEmergencyPlan plan) {
		if (EntityUtils.getState(plan).equals(EntityState.MODIFIED)) {
			this.hibernateDao.update(plan);
		}

		List<SysEmergencyPlanDept> spd = EntityUtils.getValue(plan, "planDept");
		List<SysEmergencyPlanHeader> sph = EntityUtils.getValue(plan, "planHeader");
		if (spd != null) {
			for (SysEmergencyPlanDept pd : spd) {
				if (EntityUtils.getState(pd).equals(EntityState.NEW)) {
					pd.setPlanId(plan.getId());
					this.hibernateDao.save(pd);
				} else if (EntityUtils.getState(pd).equals(EntityState.MODIFIED)) {
					if (checkPlanDept(pd.getDeptId(), plan.getId())) {
						pd.setPlanId(plan.getId());
						this.hibernateDao.save(pd);
					}
				} else if (EntityUtils.getState(pd).equals(EntityState.DELETED)) {
					this.hibernateDao.delete(pd);
				}
			}
		}
		if (sph != null) {
			for (SysEmergencyPlanHeader ph : sph) {
				if (EntityUtils.getState(ph).equals(EntityState.NEW)) {
					ph.setPlanId(plan.getId());
					this.hibernateDao.save(ph);
				} else if (EntityUtils.getState(ph).equals(EntityState.MODIFIED)) {
					if (checkPlanHeader(ph.getUsername(), plan.getId())) {
						ph.setPlanId(plan.getId());
						this.hibernateDao.save(ph);
					}
				} else if (EntityUtils.getState(ph).equals(EntityState.DELETED)) {
					this.hibernateDao.delete(ph);
				}
			}
		}
	}

	/**
	 * 判断当前要发起流程的业务的businessId是否正处于一个流程实例中
	 * 
	 * @return
	 */
	@Expose
	public boolean isInProcess(String businessId) {
//		if (UfloUtils.isInProcessInstance(businessId)) {
//			return false;
//		} else if (UfloUtils.hasHistoryProcessInstance(businessId)) {
//			return false;
//		}
		return true;
	}

	/**
	 * 根据deptId和PlanId判断SysEmergencyPlanDept中是否已存在此数据
	 * 
	 * @param deptId
	 * @param planId
	 * 
	 * @return true表示没有，false表示有
	 */
	public boolean checkPlanDept(String deptId, String planId) {
		String hql = "select count(*) from SysEmergencyPlanDept where planId=:planId and deptId=:deptId and invalid=false";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("deptId", deptId);
		map.put("planId", planId);
		int i = this.hibernateDao.queryForInt(hql, map);
		if (i == 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 根据username和PlanId判断SysEmergencyPlanHeader中是否已存在此数据
	 * 
	 * @return true表示没有，false表示有
	 * @param username
	 * @param planId
	 * @return
	 */
	public boolean checkPlanHeader(String username, String planId) {
		String hql = "select count(*) from SysEmergencyPlanHeader where planId=:planId and username=:username and invalid=false";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("username", username);
		map.put("planId", planId);
		int i = this.hibernateDao.queryForInt(hql, map);
		if (i == 0) {
			return true;
		} else {
			return false;
		}
	}
}
